package ua.maxicash.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;
import ua.maxicash.dao.AppDao;
import ua.maxicash.dao.EmployerDao;
import ua.maxicash.dao.WorkerDao;
import ua.maxicash.exceptions.NoSuchEmailInSystemException;
import ua.maxicash.vo.Employer;
import ua.maxicash.vo.SystemUser;
import ua.maxicash.vo.Worker;

import javax.annotation.Resource;
import java.util.Map;

@Service("confirmationService")
public class ConfirmationServiceImpl implements ConfirmationService {

    @Autowired
    NotifyService notifyService;

    @Autowired
    AppDao appDao;

    @Autowired
    WorkerDao workerDao;

    @Autowired
    EmployerDao employerDao;

    @Autowired
    AppService appService;

    @Resource
    private Map recoveryMap;

    @Resource
    private Map loginMap;

    @Override
    public void recoverPassword(String email) throws NoSuchEmailInSystemException {
        if (appDao.getSystemUserByEmail(email) != null) {
            Long time;
            synchronized (this) {
                time = System.currentTimeMillis();
                recoveryMap.put(email, time);
            }
            notifyService.sendRecoveryInformation(email, time);
        } else {
            throw new NoSuchEmailInSystemException("Database doesn't contain user with email " + email);
        }
    }

    @Override
    public boolean isInRecoveryMap(String email, Long idRecovery) {
        return recoveryMap.containsKey(email) && recoveryMap.get(email).equals(idRecovery);
    }


    public String changePassword(String oldPass, String newPass, String confirmPass, User user) {
        PasswordEncoder encoder = new Md5PasswordEncoder();
        String oldPassword = encoder.encodePassword(oldPass, null);

        SystemUser su = appService.getSystemUserByEmail(user.getUsername());

        if (user.getPassword().equals(oldPassword)) {
            if (newPass.equals(confirmPass)) {
                su.setPassword(encoder.encodePassword(newPass, null));
                appService.saveSystemUser(su);
            } else {
                return " {\"isOk\" : false , \"message\" : \"New password does not match confirmation\" } ";
            }
        } else {
            return " {\"isOk\" : false , \"message\" : \"Old password does not match actual\" } ";
        }

        return " {\"isOk\" : true } ";
    }

    public void changePassword(String newPass, SystemUser su) {

        PasswordEncoder encoder = new Md5PasswordEncoder();
        su.setPassword(encoder.encodePassword(newPass, null));
        recoveryMap.remove(su.getEmail());
        appService.saveSystemUser(su);


    }

    @Override
    public void enableUser(String email) {
        SystemUser su = appService.getSystemUserByEmail(email);
        su.setEnabled(true);
        if (su instanceof Worker) {
             workerDao.updateWorker((Worker)su);
        }
        if (su instanceof Employer) {
             employerDao.updateEmployer((Employer) su);
        }
        loginMap.remove(email);
    }

    @Override
    public boolean isInLoginMap(String email, Long idLogin) {
        return loginMap.containsKey(email) && loginMap.get(email).equals(idLogin);
    }

    @Override
    public void addToLoginMap(String email) {
        Long time;
            synchronized (this) {
                time = System.currentTimeMillis();
                loginMap.put(email, time);
            }
            notifyService.sendLoginInformation(email, time);
    }
}
